package com.fnzn.entranceGuard.api;

import com.fnzn.entranceGuard.constant.GuardConstant;
import com.fnzn.entranceGuard.entity.*;
import com.fnzn.entranceGuard.entity.sys.SysUserRole;
import com.fnzn.entranceGuard.mapper.*;
import com.fnzn.entranceGuard.rest.guard.UsrUtil;
import com.fnzn.entranceGuard.service.AuthGuardService;
import com.fnzn.entranceGuard.service.ICallLogService;
import com.fnzn.entranceGuard.service.IInitialQrManageService;
import com.fnzn.entranceGuard.service.ICurrentUserBeanService;
import com.fnzn.entranceGuard.service.community.ICommunityInfoService;
import com.fnzn.entranceGuard.util.DateTools;
import com.fnzn.entranceGuard.util.QRGenerate;
import com.fnzn.entranceGuard.util.ResponseUtil;
import com.fnzn.entranceGuard.util.qrCode.QRCodeEncoder;
import com.fnzn.entranceGuard.util.tree.TreeUtil;
import com.fnzn.entranceGuard.vo.DeviceTree;
import com.fnzn.entranceGuard.vo.GuardRole;
import com.github.pig.common.bean.aop.SystemControllerLog;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.IdGenerate;
import com.github.pig.common.util.SendMsgUtil;
import com.github.pig.common.web.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.util.ListUtils;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.*;

/**
 * Created by sxf 2018/05/23
 */

@Controller
@Slf4j
@RequestMapping("/api")
public class GuardApi extends BaseController {

    /**
     * 自主二维码有效时间 （秒）
     */
    @Value("${qr.shareInterval}")
    private Integer shareInterval;
    //短信域名
    @Value("${qr.smsUrl}")
    private String smsUrl;
    @Autowired
    private GuardQrInfoMapper infoMapper;
    @Autowired
    private GuardQrShareMapper shareMapper;
    @Autowired
    private GuardDeviceMapper deviceMapper;
    @Autowired
    private GuardRoleDeviceMapper roleMapper;
    @Autowired
    private AuthGuardService authGuardService;
    @Autowired
    private GuardHubCodeMapper codeMapper;
    @Autowired
    private ICallLogService callLogService;
    @Autowired
    private ICurrentUserBeanService ICurrentUserBeanService;
    @Autowired
    private ICommunityInfoService communityInfoService;
    @Autowired
    private IInitialQrManageService iInitialQrManageService;

    @Value("${qr.interval}")
    private Integer interval;

    /**
     * @param request
     * @param response
     * @param communityId 社区ID
     * @return
     */
    @RequestMapping(value = "/generate", method = RequestMethod.GET)
    @ResponseBody
    @SystemControllerLog(description = "生成二维码")
    public ResponseUtil generate(HttpServletRequest request, HttpServletResponse response,
                                 @RequestParam("communityId") String communityId) {
        ResponseUtil r = new ResponseUtil();
        try {
            String userId = getUserName();
            if (StringUtils.isBlank(userId)) {
                r.fail("401", "无权限");
                return r;
            }
            //有人云是否链接
            if (UsrUtil.getInstance() == null){
                log.error("生成二维码：有人云断开连接，"+userId+" 返回结果将不被记录。");
            }
            //保存二维码信息
            GuardQrInfo info = new GuardQrInfo();
            info.setCommunityId(communityId);
            info.setIsValid(GuardQrInfo.ISVALIAD);
            info.setStatus(GuardConstant.QR_VALID);
            info.setUserId(userId);
            info.setId(UUID.randomUUID().toString());
            info.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            String content = QRGenerate.generateCompany(userId, Integer.parseInt(communityId),DateTools.getSysDataByMinute("ddHHmmss",interval));
            //获取二维码内容
            info.setContent(content);
            infoMapper.insert(info);
            QRCodeEncoder encoder = new QRCodeEncoder();
            BufferedImage image = encoder.encoderQRCode(QRGenerate.generateQr(content), "", "png", "UTF-8", 4, null, null, null, 6, null, null);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            InputStream is = new ByteArrayInputStream(os.toByteArray());
            BASE64Encoder baseEncoder = new BASE64Encoder();
            String base64Img = baseEncoder.encode(os.toByteArray());

//            // 脱机二维码
//            BufferedImage image_bak = encoder.encoderQRCode(QRGenerate.generateQrMost(content), "", "png", "UTF-8", 4, null, null, null, 6, null, null);
//            ByteArrayOutputStream os_bak = new ByteArrayOutputStream();
//            ImageIO.write(image_bak, "png", os_bak);
//            InputStream is_bak = new ByteArrayInputStream(os_bak.toByteArray());
//            BASE64Encoder baseEncoder_bak = new BASE64Encoder();
//            String base64Img_bak = baseEncoder.encode(os_bak.toByteArray());

            Map<String,Object> map = new HashMap<>();
            map.put("resource",base64Img);
            map.put("resourceBak", content);
            map.put("qrId",info.getId());
            r.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("生成二维码:",e);
            r.fail("500", e.getMessage());
        }
        return r;
    }

    @RequestMapping(value = "/generateEmu", method = RequestMethod.GET)
    @ResponseBody
    @SystemControllerLog(description = "生成二维码  仿真环境")
    public ResponseUtil generateEmu(HttpServletRequest request, HttpServletResponse response,@RequestParam("communityId") String communityId,
                                    @RequestParam("type") String type) {
        ResponseUtil r = new ResponseUtil();
        try {
            String userId = getUserName();
            if (StringUtils.isBlank(userId)) {
                r.fail("401", "无权限");
                return r;
            }
            //有人云是否链接
            if (UsrUtil.getInstance() == null){
                log.error("生成二维码：有人云断开连接，"+userId+" 返回结果将不被记录。");
            }
            if("manager".equals(type)){
                userId = "ys_test";
            }
            //保存二维码信息
            GuardQrInfo info = new GuardQrInfo();
            info.setCommunityId(communityId);
            info.setIsValid(GuardQrInfo.ISVALIAD);
            info.setStatus(GuardConstant.QR_VALID);
            info.setUserId(userId);
            info.setId(UUID.randomUUID().toString());
            info.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            String content = QRGenerate.generateCompany(userId, Integer.parseInt(communityId),DateTools.getSysDataByMinute("ddHHmmss",interval));
            //获取二维码内容
            info.setContent(content);
            infoMapper.insert(info);
            QRCodeEncoder encoder = new QRCodeEncoder();
            BufferedImage image = encoder.encoderQRCode(QRGenerate.generateQr(content), "", "png", "UTF-8", 4, null, null, null, 6, null, null);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            InputStream is = new ByteArrayInputStream(os.toByteArray());
            BASE64Encoder baseEncoder = new BASE64Encoder();
            String base64Img = baseEncoder.encode(os.toByteArray());
            Map<String,Object> map = new HashMap<>();
            map.put("resource",base64Img);
            map.put("qrId",info.getId());
            r.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            r.fail("500", e.getMessage());
        }
        return r;
    }
    @RequestMapping(value = "/polling", method = RequestMethod.GET)
    @ResponseBody
    public ResponseUtil polling(String qrId,HttpServletRequest request, HttpServletResponse response) {
        ResponseUtil r = new ResponseUtil();
        try {
            /*QR qr = new QR();
             qr.setDeviceId("00012950000000000001");
             qr.setQrId("af2b14d9-740c-40ca-a095-d65de96aa40b");
             qr.setUserId("admin");
             qr.setTime(DateTools.getCurrentSysData(DateTools.FULL_FORMAT));
            infoService.checkAuth(qr);*/
            r.ok(infoMapper.selectById(qrId));
        }catch (Exception e){
            e.printStackTrace();
            r.fail("500",e.getMessage());
        }
        return r;
    }
    @RequestMapping(value = "/{shareId}/generate", method = RequestMethod.GET)
    @ResponseBody
    @SystemControllerLog(description = "APP外生成二维码")
    public ResponseUtil generate(@PathVariable("shareId") String shareId, HttpServletRequest request, HttpServletResponse response) {
        ResponseUtil r = new ResponseUtil();
        try {
            //获取分享信息
            GuardQrShare qrShare = shareMapper.selectById(shareId);
            if (qrShare != null) {
                //查看有效期
                if (DateTools.datePoorDiffSecond(qrShare.getShareTime(), DateTools.getCurrentSysData(DateTools.FULL_FORMAT)) > (shareInterval * 60)) {
                    r.fail("300", "链接已过期。");
                    return r;
                }
                //保存二维码信息
                GuardQrInfo info = new GuardQrInfo();
                info.setCommunityId(qrShare.getCommunityId());
                info.setIsValid(GuardQrInfo.ISVALIAD);
                info.setStatus("100");
                info.setUserId(qrShare.getShareFrom());
                info.setId(IdGenerate.getUUID());
                info.setShareId(shareId);
                info.setUpdateTime(new Timestamp(System.currentTimeMillis()));
                String content = QRGenerate.generateCompany(qrShare.getShareFrom(), Integer.parseInt(qrShare.getCommunityId()),DateTools.getSysDataByMinute("ddHHmmss",interval));
                info.setContent(content);
                infoMapper.insert(info);

                QRCodeEncoder encoder = new QRCodeEncoder();
                BufferedImage image = encoder.encoderQRCode(QRGenerate.generateQr(content), "", "png", "UTF-8", 4, null, null, null, 6, null, null);
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(image, "png", os);
                InputStream is = new ByteArrayInputStream(os.toByteArray());
                BASE64Encoder baseEncoder = new BASE64Encoder();
                String base64Img = baseEncoder.encode(os.toByteArray());
                Map<String, Object> map = new HashMap<>();
                map.put("resource", base64Img);
                map.put("qrId", info.getId());
                r.ok(map);
            } else {
                r.fail("403", "参数不正确，请重试。");
            }
        } catch (Exception e) {
            e.printStackTrace();
            r.fail("500", e.getMessage());
        }
        return r;
    }
    @RequestMapping(value = "/shareQr", method = RequestMethod.POST)
    @ResponseBody
    @SystemControllerLog(description = "分享二位码链接")
    public ResponseUtil shareBySMS(@RequestBody GuardQrShare qrShare, HttpServletRequest request, HttpServletResponse response) {
        ResponseUtil r = new ResponseUtil();
        try {
            //保存分享信息
            qrShare.setId(UUID.randomUUID().toString());
            String userId = getUserName();
            if (StringUtils.isNotBlank(userId)) {
                qrShare.setShareFrom(userId);
            } else {
                r.fail("401", "token已过期，请重新登陆。");
                return r;
            }
            qrShare.setShareTime(DateTools.getCurrentSysData(DateTools.FULL_FORMAT));
            shareMapper.insert(qrShare);
            //分享链接
            String content = smsUrl + "/api/qrCode.html?shareId=" + qrShare.getId();
            if (GuardQrShare.TYPE_WX.equals(qrShare.getShareType())) {
                //微信分享
                r.ok(content);
            } else {
                //分享短信
                System.out.println(content);
                SendMsgUtil.sendSmsByAliDayu(qrShare.getPhone(),content);
                r.ok("发送成功");
            }
        } catch (Exception e) {
            r.fail("500", "分享失败，原因：" + e.getMessage());
            e.printStackTrace();
        }
        return r;
    }

    @RequestMapping(value = "/getCommunity", method = RequestMethod.GET)
    @ResponseBody
    @SystemControllerLog(description = "远程开门--根据权限获取小区设备信息")
    public ResponseUtil getCommunity(String communityId) {
        ResponseUtil r = new ResponseUtil();
        r.ok();
        try {
//            String username = getUserName();
//            if (StringUtils.isNotBlank(username)) {
//                //查询顺序  userID-->-->roleId-->小区-->树结构
//                List<SysUserRole> roleIdList = communityInfoService.getRoleId(username, communityId);
//                StringBuffer roleIds = new StringBuffer();
//                StringBuffer deviceIds = new StringBuffer();
//                String dIds = "";//去重后的设备ID
//                for (SysUserRole role : roleIdList) {
//                    if(StringUtils.isBlank(role.getRoleId())){
//                        continue;
//                    }
//                        roleIds.append(role.getRoleId());
//                        roleIds.append(",");
//                }
//                String[] rIds = roleIds.toString().split(",");
//                for(String rid :rIds){
//                    List<GuardRoleDevice> list = roleMapper.selectByRoleId(rid);
//                    for (GuardRoleDevice g : list ){
//                        deviceIds.append(g.getDeviceIds());
//                        deviceIds.append(",");
//                    }
//                }
//                //对设备ID去重
//                if (deviceIds.length() > 0) {
//                    String[] prodCodeArr = deviceIds.substring(0, deviceIds.length() - 1).split(",");
//                    Arrays.sort(prodCodeArr);
//                    Set<String> prodCodeSet = new HashSet<>();
//                    prodCodeSet.addAll(Arrays.asList(prodCodeArr));
//                    prodCodeArr = prodCodeSet.toArray(new String[]{});
//                    dIds = Arrays.toString(prodCodeArr);
//                    deviceIds = null;
//                } else {
//                    r.fail("404", "您没有权限内门禁。");
//                    return r;
//                }
//                List<DeviceTree> devices =  deviceMapper.listTree(communityId);
//                List<DeviceTree> list = new ArrayList<>();
//                list.addAll(devices);
//                //根据小区筛选设备 去除两侧中括号
//                for (DeviceTree t : devices){
//                    //删除楼宇设备
//                    if(StringUtils.isNotBlank(t.getDeviceId()) && !dIds.contains(t.getDid())){
//                        list.remove(t);
//                    }
//                }
//                r.ok( TreeUtil.buildByRecursive(list,"0"));
//            } else {
//                r.fail("401", "token解析错误，请重新登陆。");
//            }
        } catch (Exception e) {
            e.printStackTrace();
            r.fail("500", e.getMessage());
        }
        return r;
    }


    @RequestMapping(value = "/remoteOpenDoor", method = RequestMethod.POST)
    @ResponseBody
    @SystemControllerLog(description = "远程开门")
    public ResponseUtil remoteOpenDoor(@RequestBody GuardDevice device) {
        ResponseUtil r = new ResponseUtil();
        try{
            String userId = getUserName();
            if(StringUtils.isNotBlank(userId)){
                log.info("远程开门："+getUserName()+",门禁名称："+device.getDeviceName());
            }else{
                log.error("401","获取token失败，请重新登陆。");
                r.fail("401","获取token失败，请重新登陆。");
                return r;
            }
            //开门
            String deviceId = device.getDeviceId();
            UsrUtil.publishForDevId(UsrUtil.PublishFormat(new byte[1],GuardConstant.TYPE_SCAN), deviceId);
            Thread.sleep(1000);
            UsrUtil.publishForDevId(UsrUtil.PublishFormat(new byte[1],GuardConstant.TYPE_SCAN), deviceId);
        }catch (Exception e){
            e.printStackTrace();
            r.fail("500","开门失败："+e.getMessage());
        }
        return r;

    }
    /**
     * 存入通话记录
     * @return
     */
    @RequestMapping(value = "/callLog", method = RequestMethod.POST)
    @ResponseBody
    public ResponseUtil callLog(@RequestBody List<CallLog> logs) {
        ResponseUtil r = new ResponseUtil();
        try{
            callLogService.insertBatch(logs);
        }catch (Exception e){
            e.printStackTrace();
            r.fail("500","插入失败："+e.getMessage());
        }
        return r;

    }

    /**
     * 获取初始化二维码
     * @param type
     * @param communityId
     * @return
     */
    @RequestMapping(value = "/getQr", method = RequestMethod.GET)
    @ResponseBody
    public ResponseUtil getQr(String type, String communityId, String buildingId, String unitId) {
        ResponseUtil r = new ResponseUtil();
        try{
            String username = getUserName();
            //admin: type="0"
            if ("admin".equals(username)) {
                List<InitialQrManage> list = iInitialQrManageService.getByType(CommonConstant.TYPE_ADMIN);
                if(!ListUtils.isEmpty(list)) {
                    r.ok(getImg(list.get(0)));
                    return r;
                }
                r.fail("500","超级管理员权限二维码为空");
                return r;
            }
            if(CommonConstant.TYPE_PROPERTY.equals(type)) {
                List<InitialQrManage> list = iInitialQrManageService.getByTypeAndCommunityId(CommonConstant.TYPE_PROPERTY, communityId);
                if(!ListUtils.isEmpty(list)) {
                    r.ok(getImg(list.get(0)));
                    return r;
                }
                r.fail("500","物业管理员权限二维码为空");
                return r;
            } else if(CommonConstant.TYPE_OWNER.equals(type)) {
                CommunityBuilding building = ICurrentUserBeanService.selectByBuildingId(buildingId);
                if(building.getExistUnit()!=null && "0".equalsIgnoreCase(building.getExistUnit())){
                    List<InitialQrManage> list = iInitialQrManageService.getByTypeAndCommunityIdAndBuildingId(CommonConstant.TYPE_OWNER, communityId, buildingId);
                    if(!ListUtils.isEmpty(list)) {
                        r.ok(getImg(list.get(0)));
                        return r;
                    }
                    r.fail("500","此楼宇二维码为空");
                    return r;
                }else{
                    List<InitialQrManage> list = iInitialQrManageService.getByTypeAndCommunityIdAndBuildingIdAndUnitId(CommonConstant.TYPE_OWNER, communityId, buildingId, unitId);
                    if(!ListUtils.isEmpty(list)) {
                        r.ok(getImg(list.get(0)));
                        return r;
                    }
                    r.fail("500","此单元二维码为空");
                    return r;
                }
            } else {
                r.fail("500","未知角色类型");
            }
        }catch (Exception e){
            e.printStackTrace();
            r.fail("500", e.getMessage());
        }
        return r;
    }

    public static void main(String[] args) {
        String d = DateTools.getCurrentSysData(DateTools.FULL_FORMAT);
        System.out.println(d);
        String d1 = DateTools.getSysDataByMinute(DateTools.FULL_FORMAT, 1);
        System.out.println(d1);
     /*   try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String d1 = DateTools.getCurrentSysData(DateTools.FULL_FORMAT);
        System.out.println(d1);
        System.out.println(DateTools.datePoorDiffSecond(d, d1));*/
    }

    public String getImg(InitialQrManage initialQrManage) {
        String base64;
        try{
            if(StringUtils.isEmpty(initialQrManage.getImgPath())){
                return null;
            }
            byte[] data = null;
            File file = new File(initialQrManage.getImgPath());
            FileInputStream fileInputStream = new FileInputStream(file);
            // 对字节数组Base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            data = new byte[fileInputStream.available()];
            fileInputStream.read(data);
            fileInputStream.close();
            base64 = encoder.encode(data);
        }catch(Exception e){
            return null;
        }
        return base64;
    }

}

